GtkApplication: Add window-added/-removed signals
authorMatthias Clasen <mclasen@redhat.com>
Tue, 31 May 2011 23:12:13 +0000 (19:12 -0400)
committerMatthias Clasen <mclasen@redhat.com>
Tue, 31 May 2011 23:12:13 +0000 (19:12 -0400)
This is useful to let unrelated parts of an application (or
plugins) learn about the windows of an application. Based
on a patch by Matt Barnes,
https://bugzilla.gnome.org/show_bug.cgi?id=641087

gtk/gtkapplication.c
gtk/gtkapplication.h

index d6287d9c9b8ca95f64a028f4185ed6cd452bce9b..496a010f4e02a37d729945ff6e5a81a2a3658483 100644 (file)
  * </example>
  */
 
+enum {
+  WINDOW_ADDED,
+  WINDOW_REMOVED,
+  LAST_SIGNAL
+};
+
+static guint gtk_application_signals[LAST_SIGNAL];
+
 G_DEFINE_TYPE (GtkApplication, gtk_application, G_TYPE_APPLICATION)
 
 struct _GtkApplicationPrivate
@@ -157,6 +165,36 @@ gtk_application_init (GtkApplication *application)
                                                    GtkApplicationPrivate);
 }
 
+static void
+gtk_application_window_added (GtkApplication *application,
+                              GtkWindow      *window)
+{
+  GtkApplicationPrivate *priv = application->priv;
+
+  priv->windows = g_list_prepend (priv->windows, window);
+  gtk_window_set_application (window, application);
+  g_application_hold (G_APPLICATION (application));
+
+  g_signal_connect (window, "focus-in-event",
+                    G_CALLBACK (gtk_application_focus_in_event_cb),
+                    application);
+}
+
+static void
+gtk_application_window_removed (GtkApplication *application,
+                                GtkWindow      *window)
+{
+  GtkApplicationPrivate *priv = application->priv;
+
+  g_signal_handlers_disconnect_by_func (window,
+                                        gtk_application_focus_in_event_cb,
+                                        application);
+
+  g_application_release (G_APPLICATION (application));
+  gtk_window_set_application (window, NULL);
+  priv->windows = g_list_remove (priv->windows, window);
+}
+
 static void
 gtk_application_class_init (GtkApplicationClass *class)
 {
@@ -170,7 +208,45 @@ gtk_application_class_init (GtkApplicationClass *class)
   application_class->quit_mainloop = gtk_application_quit_mainloop;
   application_class->run_mainloop = gtk_application_run_mainloop;
 
+  class->window_added = gtk_application_window_added;
+  class->window_removed = gtk_application_window_removed;
+
   g_type_class_add_private (class, sizeof (GtkApplicationPrivate));
+
+  /**
+   * GtkApplication::window-added:
+   * @application: the #GtkApplication which emitted the signal
+   * @window: the newly-added #GtkWindow
+   *
+   * Emitted when a #GtkWindow is added to @application through
+   * gtk_application_add_wi!ndow().
+   *
+   * Since: 3.2
+   */
+  gtk_application_signals[WINDOW_ADDED] =
+    g_signal_new ("window-added", GTK_TYPE_APPLICATION, G_SIGNAL_RUN_FIRST,
+                  G_STRUCT_OFFSET (GtkApplicationClass, window_added),
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__OBJECT,
+                  G_TYPE_NONE, 1, GTK_TYPE_WINDOW);
+
+  /**
+   * GtkApplication::window-removed:
+   * @application: the #GtkApplication which emitted the signal
+   * @window: the #GtkWindow that is being removed
+   *
+   * Emitted when a #GtkWindow is removed from @application,
+   * either as a side-effect of being destroyed or explicitly
+   * through gtk_application_remove_window().
+   *
+   * Since: 3.2
+   */
+  gtk_application_signals[WINDOW_REMOVED] =
+    g_signal_new ("window-removed", GTK_TYPE_APPLICATION, G_SIGNAL_RUN_FIRST,
+                  G_STRUCT_OFFSET (GtkApplicationClass, window_removed),
+                  NULL, NULL,
+                  g_cclosure_marshal_VOID__OBJECT,
+                  G_TYPE_NONE, 1, GTK_TYPE_WINDOW);
 }
 
 /**
@@ -224,22 +300,11 @@ void
 gtk_application_add_window (GtkApplication *application,
                             GtkWindow      *window)
 {
-  GtkApplicationPrivate *priv;
-
   g_return_if_fail (GTK_IS_APPLICATION (application));
 
-  priv = application->priv;
-
-  if (!g_list_find (priv->windows, window))
-    {
-      priv->windows = g_list_prepend (priv->windows, window);
-      gtk_window_set_application (window, application);
-      g_application_hold (G_APPLICATION (application));
-
-      g_signal_connect (window, "focus-in-event",
-                        G_CALLBACK (gtk_application_focus_in_event_cb),
-                        application);
-    }
+  if (!g_list_find (application->priv->windows, window))
+    g_signal_emit (application,
+                   gtk_application_signals[WINDOW_ADDED], 0, window);
 }
 
 /**
@@ -262,22 +327,11 @@ void
 gtk_application_remove_window (GtkApplication *application,
                                GtkWindow      *window)
 {
-  GtkApplicationPrivate *priv;
-  GList *link;
-
   g_return_if_fail (GTK_IS_APPLICATION (application));
 
-  priv = application->priv;
-  link = g_list_find (priv->windows, window);
-  if (link)
-    {
-      g_signal_handlers_disconnect_by_func (window,
-                                            gtk_application_focus_in_event_cb,
-                                            application);
-      priv->windows = g_list_remove_link (priv->windows, link);
-      g_application_release (G_APPLICATION (application));
-      gtk_window_set_application (window, NULL);
-    }
+  if (g_list_find (application->priv->windows, window))
+    g_signal_emit (application,
+                   gtk_application_signals[WINDOW_REMOVED], 0, window);
 }
 
 /**
index c915e2dc864c0dfcc98e9cf8a5aa5d57eec1b3f2..6caa4081a9c6e8d5a2258b9a943e377257f2584c 100644 (file)
@@ -55,8 +55,13 @@ struct _GtkApplicationClass
 {
   GApplicationClass parent_class;
 
+  void (*window_added)   (GtkApplication *application,
+                          GtkWindow      *window);
+  void (*window_removed) (GtkApplication *application,
+                          GtkWindow      *window);
+
   /*< private >*/
-  gpointer padding[16];
+  gpointer padding[14];
 };
 
 GType                   gtk_application_get_type                        (void) G_GNUC_CONST;